home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
zeno25.zip
/
ZENO.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-01-19
|
14KB
|
421 lines
Page 60,132
; ZENO: June 11, 1986 «RM120»«IP0,6»
; Modified Sept 4, 1986 by R Tansky to fix 40-character mode
; Modified Oct 31, 1986 by R Tansky to further fix 40-character mode and to
; fix graphics mode
; Modified Jan 28, 1987 by C Blum to add code to support TTY mode call
; (AH=0Eh). Required by some clone BIOS implementations (DTK/ERSO for
; one) because they do not issue any 'set cursor' calls from within the
; TTY mode call. This causes ZENO to lose its video offset and the
; display goes out to lunch.
; Modified May 29, 1987 by Lynn Ransdell to support KEDIT 3.51
; Modified Dec 13, 1988 by Glenn K. Smith to do snow suppression and to add
; a /S option to enable this suppression. Use of this switch causes
; ZENO to be around 2 1/2 times slower (ZENOTEST=66 @10mhz).
; Modified Jan 15, 1988 by Glenn K. Smith to speed up snow checking and to
; fix a bug. Some programs didn't work right with ZENO. Mainly those
; which modified the cursor position without calling ZENO (Procomm+,
; Turbo Pascal CRT unit and others). The fix required calculating the
; screen offset using the BIOS cursor everytime a character was placed
; on the screen. ZENOTEST now takes 46 seconds @10mhz instead of 66.]
; Modified Jan 19, 1989 by Howard Flank to work correctly with AMI 386 BIOS.
; Rewrote the command line scanner, accepts upper/lower, switches may be
; preceeded by slash, dash, or space, etc. Changed the /K switch to the
; more standard /U switch. Put cursor recalc code for ERSO BIOS on /E
; switch. Added /H switch to display a help screen. 'Prettied' up the
; messages. Made redundant code into subroutines. Changed 'kill' code
; for compatibility with TopView and moved 'kill' message out of resident
; code. Resident code is 200 bytes smaller.
cseg segment para public 'code'
zeno proc far
assume cs:cseg, ds:cseg, es:cseg, ss:cseg
org 100h ; for .COM file
;------------------------------*
; ENTER HERE ON INITIAL LOAD *
;------------------------------*
start: jmp near ptr load_pgm
CR equ 0Dh
LF equ 0Ah
video_vector dd 0
core_seg dw 0
bios_cursor_pos label dword
bios_ofst dw 00h ; offset for active page
dw 40h ; segment for bios data
crt_mode db 2 ; passes if 4, 5, or 6
active_page db 0
cursor_type dw 0B0Ch ; DOS cursor
video_posn label dword
video_ofst dw 0 ; offset against video_seg
video_seg dw 0
video_addr dw 0
onesixty db 160
snow db 0 ; Snow suppression flag
recalc db 0
;---------------------------*
; ENTER HERE FROM INT 10H *
;---------------------------*
video_int: sti ; interrupts on
pushf ; save flags
cmp cs:crt_mode,3 ; check for color text 1
je video_keep ; go if so
cmp cs:crt_mode,2 ; check for color text 2
je video_keep ; go if so
cmp cs:crt_mode,7 ; check for b/w
je video_keep ; go if so
cmp ah,0 ; check for set mode
je video_keep ; if so, continue
jmp short video_rtn ; go if graphics / 40 col
video_keep: push ds ; save regs
push es
push di
push ax
push cx
push dx
push cs ; set ds for addressibility
pop ds
cmp recalc,3 ; ERSO cursor recalc req'd?
jne video_func ; no:
les di,bios_cursor_pos ; yes: recalc
push ax
push cx
mov ax,es:[di]
call calc_offset ; calc offset into video ram
and recalc,0FEh ; clear recalc flag
pop cx
pop ax
video_func: cmp ah,1 ; to set type
je $set_type
cmp ah,0 ; to set mode
je $set_mode
cmp ah,5 ; to set page
je $set_page
cmp ax,0F0F0h ; uninstall code
je $remove ; go if found
cmp bh,active_page ; check if active page
jne video_exit ; no: use BIOS
cmp ah,14 ; to write as TTY
je $TTY
cmp ah,2 ; to set cursor
je set_cursor
cmp ah,3 ; to read cursor
je $read_cursor
cmp cx,1 ; check multiple write
jne video_exit ; yes: use BIOS
cmp ah,10 ; to write char only
je write_char
cmp ah,9 ; to write char/attr
je $write_both
video_exit: pop dx ; restore regs
pop cx
pop ax
pop di
pop es
pop ds
video_rtn: popf ; restore flags
jmp cs:dword ptr video_vector ; hand off interrupt to BIOS
$TTY: jmp TTY
$write_both: jmp write_both
$read_cursor: jmp read_cursor
$set_page: jmp set_page
$set_type: jmp set_type
$set_mode: jmp set_mode
$remove: jmp remove
write_char: Call Display1
jmp zeno_exit
set_cursor: add video_ofst,2 ; for next char
les di,bios_cursor_pos ; get bios
inc byte ptr es:[di] ; assume next
cmp es:[di],dx ; check if next
je offset_ready ; go if next
mov ax,dx ; get req posn
mov es:[di],ax ; save req posn
call calc_offset ; calc offset into video ram
offset_ready: mov cx,video_ofst ; offset in cx
shr cx,1 ; for byte count
mov ah,14 ; cursor MSB register
mov dx,video_addr ; 6845 index addr
mov al,ah ; get register
out dx,al ; send register
inc dx ; 6845 data addr
mov al,ch ; get cursor MSB
out dx,al ; send cursor MSB
dec dx ; 6845 index addr
mov al,ah ; cursor MSB register
inc al ; cursor LSB register
out dx,al ; send register
inc dx ; 6845 data addr
mov al,cl ; get cursor LSB
out dx,al ; send cursor LSB
jmp zeno_exit
write_both: mov ah,bl ; get attribute
push ax
les di,bios_cursor_pos
mov ax,es:[di]
Call Calc_Offset
les di,video_posn ; get screen position
cmp snow,1 ; Snow suppression?
je color ; yes:
pop ax
stosw ; Place char+attr onto screen
jmp short zeno_exit
color: mov dx,03DAh
cli
WaitNoH1: in al, dx ; Get 6845 Status
test al,8 ; Check vert retrace
jnz WaitE1 ; In Progress? go
rcr al,1 ; Wait for end of
jc WaitNoH1 ; horizontial retrace
WaitH1: in al,dx ; Get 6845 status again
rcr al,1 ; Wait for horizontial
jnc WaitH1 ; retrace
WaitE1: pop ax
stosw
sti
zeno_exit: pop dx ; restore regs
pop cx
zeno_exit2: pop ax
pop di
pop es
pop ds
popf ; restore flags
iret ; return from interrupt
set_recalc: or recalc,1 ; set cursor pos recalc, then
$video_exit: jmp video_exit ; use BIOS routines
read_cursor: pop dx ; pop regs off stack
pop cx
les di,bios_cursor_pos ; get bios
mov dx,es:[di] ; get bios cursor posn
mov cx,cursor_type ; get type
jmp short zeno_exit2
set_page: mov active_page,al ; save page
xor ah,ah ; page in ax
shl ax,1 ; for word count
add ax,50h ; offset for page zero
mov bios_ofst,ax ; save offset
jmp video_exit ; pass to bios
set_type: mov cursor_type,cx ; save type
jmp video_exit ; pass to bios
set_mode: mov crt_mode,al ; save mode
mov video_ofst,0 ; top left
jmp video_exit ; done
TTY: cmp al,' ' ; control characters?
jb set_recalc ; yes: set for recalc, use BIOS
cmp video_ofst,25*80*2-2 ; scroll imminent ?
jnb set_recalc ; yes: set for recalc, use BIOS
Call Display1 ; display w/ or w/o snow
les di,bios_cursor_pos ; get bios
mov dx,es:[di] ; get current pos
inc dl ; next char pos
cmp dl,79 ; new line ?
ja TTY_new_line ; yes, adjust
jmp set_cursor ; set cursor
TTY_new_line: mov dl,0 ; col = 1
inc dh ; inc row
jmp set_cursor ; set cursor
;---- SUBROUTINE: DISPLAY A CHAR W/ OR W/O SNOW SUPPRESSION -------------------
Display1 Proc
push ax
les di,bios_cursor_pos
mov ax,es:[di]
Call Calc_Offset
les di,video_posn ; get screen position
cmp snow,1
je SuppressSnow
pop ax
stosb
ret
SuppressSnow: mov dx,03DAh ; Put char, snow suppressed
cli
WaitNoH: in al, dx ; Get 6845 Status
test al,8 ; Check vert retrace
jnz WaitE ; In Progress? go
rcr al,1 ; Wait for end of
jc WaitNoH ; horizontial retrace
WaitH: in al, dx ; Get 6845 status again
rcr al, 1 ; Wait for horizontial
jnc WaitH ; retrace
WaitE: pop ax
stosb
sti
ret
Display1 EndP
;---- SUBROUTINE: CALC THE VIDEO OFFSET FROM THE CURSOR POSITION (In AX) ------
Calc_Offset Proc
mov cx,ax ; copy posn
mov al,ah ; rows in al
mul onesixty ; for bytes
xor ch,ch ; cols in cx
shl cx,1 ; for video
add ax,cx ; offset in ax
mov video_ofst,ax ; store offset
ret
Calc_Offset EndP
;---- REMOVE ZENO FROM MEMORY -------------------------------------------------
remove: mov ax,2510h ; to set video vector
lds dx,video_vector ; get original
int 21h ; set vector
push cs ; set es to seg to be freed
pop es
mov ah,49h ; for free memory fn
int 21h ; do free memory
push cs ; set ds
pop ds
mov bx,2Ch ; set for environment segment
mov es,0[bx]
mov ah,49h ; for free memory fn
int 21h ; do free memory
jmp zeno_exit ; return to ZENO/U
end_core:
;------------------------------*
; ENTER HERE TO LOAD PROGRAM *
;------------------------------*
;---- CHECK FOR COLOR SCREEN; SET VIDEO SEGMENT -------------------------------
load_pgm: push cs ; set ds to this seg
pop ds
mov video_seg,0B000h ; assume mono
mov video_addr,03B4h ; assume mono
int 11h ; for equip check
and ax,30h ; isolate adapter
cmp ax,30h ; check for mono
je get_switch ; go if found
mov video_seg,0B800h ; reset for color
mov video_addr,03D4h ; reset for color
;---- GET ANY COMMAND LINE SWITCHES -------------------------------------------
get_switch: mov si,80h ; ptr to parm length
xor cx,cx ; clear cx
mov cl,byte ptr [si] ; put parm len in cx
jcxz set_vars ; if no parms, install
inc si ; ptr to parms
get_char: lodsb ; get next byte of cmd line
cmp al,'/' ; skip seperators
jna next_char
cmp al,'a' ; is char lower case?
jb check_switch ; no:
sub al,20h ; yes: make it upper
check_switch: cmp al,'S' ; /S sets snow suppression
je suppress
cmp al,'U' ; /U uninstalls ZENO
je uninstall
cmp al,'E' ; /E set ERSO BIOS compatiblity
je ERSO
cmp al,'H' ; /H displays a help screen
je help
lea dx,invalid_msg ; else: invalid switch message
mov ah,9 ; for print fn
int 21h ; print message
help: lea dx,help_msg ; give user some help
msg: mov ah,9 ; for print fn
int 21h ; print message
int 20h ; exit to DOS
ERSO: mov recalc,2 ; set cursor recalc on
next_char: loop get_char
jmp short set_vars
uninstall: mov ax,0F0F0h ; set for uninstall
int 10h ; order ZENO removed
lea dx,removed_msg ; get 'removed' message
cmp bx,2Ch ; actually uninstalled?
je msg ; yes:
lea dx,wasnt_msg ; no: get 'not removed" msg
jmp short msg
suppress: inc snow ; turn on snow suppression
;---- FIND AND SET CURRENT VIDEO VARIABLES ------------------------------------
set_vars: les di,bios_cursor_pos ; set to 0040:0000
mov al,es:[di+49h] ; get current mode
mov crt_mode,al ; save mode
mov ax,es:[di+60h] ; get cursor type
mov cursor_type,ax ; save type
mov al,es:[di+62h] ; get active page
mov active_page,al ; save active page
xor ah,ah ; page in ax
shl ax,1 ; for word count
add ax,50h ; offset for page zero
mov bios_ofst,ax ; save offset
;---- SET VIDEO INTERRUPT -----------------------------------------------------
mov core_seg,cs ; set core segment
push es ; save
mov ax,3510h ; to get vector
int 21h ; get vector
mov word ptr video_vector,bx ; store offset
mov word ptr video_vector+2,es ; store segment
pop es ; restore
mov ax,2510h ; to set video vector
lea dx,video_int ; get offset, ds OK
int 21h ; set vector
;---- PRINT MESSAGES, TERMINATE AND STAY RESIDENT -----------------------------
lea dx,install_msg ; get message
mov ah,9h ; for print fn
int 21h ; print message
cmp recalc,2 ; check if ERSO mode
jb check_snow ; no:
lea dx,ERSO_msg ; yes: show message
mov ah,9h ; DOS display msg function
int 21
check_snow: cmp snow,1 ; check for snow flag
jne check_color
lea dx,snow_msg ; get message
jmp short show_msg ; show message
check_color: cmp video_seg,0B000h ; check for color
je show_finish ; skip if mono
lea dx,color_msg ; get message
show_msg: mov ah,9h ; for print fn
int 21h ; print message
show_finish: lea dx,finish_msg ; get termination
mov ah,9h ; for print fn
int 21h ; print ternination
lea ax,end_core ; last address in core
add ax,2Fh ; make bumper
mov cl,4 ; for shift
shr ax,cl ; convert to paras
mov bx,ax ; no. paras to keep
mov dx,ax ; same
mov ah,4Ah ; for setblock
int 21h ; do setblock
mov ax,3100h ; for keep, no exit code
int 21h ; exit and stay resident
install_msg db '┌──────────────────────────────────────────┐',CR,LF
db '│ ZENO 2.5 has been successfully installed │',CR,LF,'$'
snow_msg db '│ Snow suppression is enabled. │',CR,LF,'$'
ERSO_msg db '│ ERSO BIOS compatibility is enabled. │',CR,LF,'$'
color_msg db '│ If snow is present, re-install with /S │',CR,LF,'$'
finish_msg db '└──────────────────────────────────────────┘',CR,LF,'$'
removed_msg db CR,LF,'[ZENO has been removed]',CR,LF,'$'
wasnt_msg db CR,LF,'[ZENO was not resident]',CR,LF,7,'$'
invalid_msg db CR,LF,'*** Invalid Switch Specified ***',CR,LF,7,'$'
help_msg db CR,LF,'ZENO Screen Accelerator, Version 2.5 (1-19-89)',CR,LF,LF
db 'Usage: ZENO [/U] [/S] [/E] [/H]',CR,LF
db ' /U Uninstall ZENO (ZENO must be the last resident program)',CR,LF
db ' /S Suppress snow (required on some older CGA cards)',CR,LF
db ' /E Set for ERSO BIOS compatibility',CR,LF
db ' /H Displays this screen',CR,LF,'$'
zeno endp
cseg ends
end start